/**
 * ScreenShotHttpServer.java
 * 版权所有(C) 2014
 * 创建者:cuiran 2014-4-9 下午2:26:37
 */
package com.ghyf.mplay.net.shot;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.net.ServerSocket;
import java.net.Socket;

import java.util.Locale;



import org.apache.http.ConnectionClosedException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.HttpServerConnection;
import org.apache.http.HttpStatus;
import org.apache.http.MethodNotSupportedException;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;


import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpResponseFactory;
import org.apache.http.impl.DefaultHttpServerConnection;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpRequestHandlerRegistry;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ImmutableHttpProcessor;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.http.util.EntityUtils;

import android.graphics.Bitmap;
import android.os.Handler;

import com.ghyf.mplay.application.CookieConstants;
import com.ghyf.mplay.application.UserInfoSingleton;
import com.ghyf.mplay.util.LogUtil;
import com.ghyf.mplay.util.ScreenShotFb;
import com.ghyf.mplay.value.ConstantValue;


/**
 * 截屏HttpServer 访问截图地址:http://本机IP:9116/s.bmp
 * @author cuiran
 * @version 1.0.0
 */
public class ScreenShotHttpServer {

	private final static String TAG="ScreenShotHttpServer";
	/**截图服务对应端口**/
	public	final static  int SERVER_PORT = 9116;
	static Thread t;
	/**
	 * 启动截屏服务<br>
	 * 2014-4-25 下午4:19:22
	 *
	 */
	public static void start(){
	
		try {//ConstantValue.SHOT_SDCARD_DIR /sata
			t = new RequestListenerThread(SERVER_PORT,ConstantValue.SHOT_SDCARD_DIR);
			t.setDaemon(false);  
			t.start();      //start the webservice server  
		} catch (IOException e) {
		
			e.printStackTrace();
		}  
	      
		
	}
	
	/**
	 * 关闭截屏服务<br>
	 * 2014-4-25 下午4:19:22
	 *
	 */
	public static  void stop(){
		 if (t == null) {
		     return;
		    }
		    t.interrupt();
		    try {
		      t.join(5000);
		    } catch (InterruptedException e) {
		      e.printStackTrace();
		    }
	}
	 static class HttpFileHandler implements HttpRequestHandler  {

	        @SuppressWarnings("unused")
			private final String docRoot;

	        public HttpFileHandler(final String docRoot) {
	            super();
	            this.docRoot = docRoot;
	        }
	        /**
	         * Bitmap转byte[] <br>
	         * 2014-10-15 上午10:54:01
	         * @param bitmap
	         * @return
	         *
	         */
	        public  byte[] getBitmapByte(Bitmap bitmap){  
	            ByteArrayOutputStream out = new ByteArrayOutputStream();  
	            bitmap.compress(Bitmap.CompressFormat.PNG, 30, out);  
	            try {  
	                out.flush();  
	                out.close();  
	            } catch (IOException e) {  
	                e.printStackTrace();  
	            }  
	            return out.toByteArray();  
	        }  
	        Bitmap bm=null;
	        byte[] data=null;
	       volatile boolean isFlag=false;
	       WeakReference<Bitmap> mReference=null;
	        Handler handler=new Handler();
	        Runnable runnable = new Runnable() { 
	            @Override 
	            public void run() { 
	            	isFlag=false;
	            } 
	        }; 
	        public void handle(
	                final HttpRequest request,
	                final HttpResponse response,
	                final HttpContext context) throws HttpException, IOException {

	        	try{
	        		  String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
	  	            if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
	  	                throw new MethodNotSupportedException(method + " method not supported");
	  	            }
//	  	            String target = request.getRequestLine().getUri();

	  	            if (request instanceof HttpEntityEnclosingRequest) {
	  	                HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
	  	                byte[] entityContent = EntityUtils.toByteArray(entity);
	  	                LogUtil.i(TAG,"Incoming entity content (bytes): " + entityContent.length);
	  	            }
	  	            boolean isFlag2= UserInfoSingleton.getBoolean(CookieConstants.IsPowerOff);
	  	            
	  	            if(!isFlag&&!isFlag2){
	  	            	isFlag=true;
	  	            	bm=ScreenShotFb.shot();
	  	           	    mReference = new WeakReference<Bitmap>(bm);
	  				  
	  				 	 // 获取软引用中的位图变量
	  					Bitmap bitmap = mReference.get();
	  					data=getBitmapByte(bitmap);
	  					handler.postDelayed(runnable, 5000);
	  	             }
	  	            
	  	             if(null==data)return;
	                  HttpEntity arrayEntity=new ByteArrayEntity(data);
	                  response.setEntity(arrayEntity);
	   
	        	}catch(Exception e){
	        		LogUtil.e(TAG, "handle error", e);
	        	}finally{
	        		  // 先判断是否已经回收----
  				 	if(bm != null && !bm.isRecycled()){ 
  				 		// 回收并且置为null
  				 		bm.recycle(); 
  				 		// 释放硬应用
  				 		bm = null; 
  				 	} 
	        	}
	          
	        }

	    }
	
	static class WebServiceHandler implements HttpRequestHandler {


		public WebServiceHandler() {
			super();
		}


		public void handle(final HttpRequest request,
				final HttpResponse response, final HttpContext context)
				throws HttpException, IOException {			


			String method = request.getRequestLine().getMethod()
					.toUpperCase(Locale.ENGLISH);
			//get uri
			String target = request.getRequestLine().getUri();
			if (method.equals("GET") ) {
				response.setStatusCode(HttpStatus.SC_OK);
				StringEntity entity = new StringEntity("<xml><method>get</method><url>" + target + "</url></xml>");
				response.setEntity(entity);
			}
			else if (method.equals("POST") )
			{
				response.setStatusCode(HttpStatus.SC_OK);
				StringEntity entity = new StringEntity("<xml><method>post</method><url>" + target + "</url></xml>");
				response.setEntity(entity);
			}
			else
			{
				throw new MethodNotSupportedException(method
						+ " method not supported");
			}
		}


	}


	static class RequestListenerThread extends Thread {


		private final ServerSocket serversocket;
		private final HttpParams params;
		private final HttpService httpService;


		public RequestListenerThread(int port,String docRoot)
				throws IOException {
			// 
			this.serversocket = new ServerSocket(port);


			// Set up the HTTP protocol processor
			HttpProcessor httpproc = new ImmutableHttpProcessor(
					new HttpResponseInterceptor[] {
							new ResponseDate(), new ResponseServer(),
							new ResponseContent(), new ResponseConnControl() });


			this.params = new BasicHttpParams();
			this.params
					.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000)
					.setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE,
							8 * 1024)
					.setBooleanParameter(
							CoreConnectionPNames.STALE_CONNECTION_CHECK, false)
					.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
					.setParameter(CoreProtocolPNames.ORIGIN_SERVER,
							"HttpComponents/1.1");


			// Set up request handlers
			HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
//			reqistry.register("*", new WebServiceHandler());  //WebServiceHandler用来处理webservice请求。
			reqistry.register("*", new HttpFileHandler(docRoot)); 

			this.httpService = new HttpService(httpproc,
					new DefaultConnectionReuseStrategy(),
					new DefaultHttpResponseFactory());
			httpService.setParams(this.params);
			httpService.setHandlerResolver(reqistry);		//为http服务设置注册好的请求处理器。


		}


		@Override
		public void run() {
			LogUtil.i(TAG,"Listening on port "
					+ this.serversocket.getLocalPort());
			LogUtil.i(TAG,"Thread.interrupted = " + Thread.interrupted()); 
			while (!Thread.interrupted()) {
				try {
					// Set up HTTP connection
					Socket socket = this.serversocket.accept();
					
					DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
					
					LogUtil.i(TAG,"Incoming connection from "
							+ socket.getInetAddress());
					
					conn.bind(socket, this.params);


					// Start worker thread
					Thread t = new WorkerThread(this.httpService, conn);
					t.setDaemon(true);
					t.start();
				} catch (InterruptedIOException ex) {
					break;
				} catch (IOException e) {
					LogUtil.e(TAG,"I/O error initialising connection thread: "
									+ e.getMessage());
					break;
				}
			}
		}
	}


	static class WorkerThread extends Thread {


		private final HttpService httpservice;
		private final HttpServerConnection conn;


		public WorkerThread(final HttpService httpservice,
				final HttpServerConnection conn) {
			super();
			this.httpservice = httpservice;
			this.conn = conn;
		}


		@Override
		public void run() {
			LogUtil.i(TAG,"New connection thread");
			HttpContext context = new BasicHttpContext(null);
			try {
				while (!Thread.interrupted() && this.conn.isOpen()) {
					
					this.httpservice.handleRequest(this.conn, context);
					
				}
			} catch (ConnectionClosedException ex) {
				LogUtil.e(TAG,"Client closed connection");
			} catch (IOException ex) {
				LogUtil.e(TAG,"I/O error: " + ex.getMessage());
			} catch (HttpException ex) {
				LogUtil.e(TAG,"Unrecoverable HTTP protocol violation: "
						+ ex.getMessage());
			} finally {
				try {
					this.conn.shutdown();
				} catch (IOException ignore) {
					LogUtil.e(TAG,"error",ignore);
				}
			}
		}
	}
}
